import os
import time

from debug.debugOut import log

"wifi管理"
class WifiManger:
    def __init__(self):
        pass
    
    """功能处理--------------------------------------------------------------------------------"""
    # 获取 Wi-Fi 无线网卡名称
    @staticmethod
    def get_wifi_ifname() -> str:
        """
        自动获取系统中第一个 Wi-Fi 无线网卡名称
        :return: 网卡名称（如 wlan0、wlp3s0），找不到返回空字符串
        """
        try:
            output = os.popen("nmcli -t -f DEVICE,TYPE device").read().strip()
            for line in output.splitlines():
                device, dev_type = line.split(":")
                if dev_type == "wifi":
                    return device
        except Exception as e:
            log.error(f"获取 Wi-Fi 网卡失败: {e}")
            return ""

    # 判断是否存在指定名称的 Wi-Fi 热点在运行
    @staticmethod
    def hotspot_connection_exists(ssid: str) -> bool:
        """
        判断是否存在指定名称的 Wi-Fi 热点连接。
        :param ssid: 要检查的连接名称
        :return: 存在则返回 True，否则 False
        """
        try:
            connections = os.popen("nmcli -t -f NAME connection show").read().splitlines()
            return ssid in connections
        except Exception as e:
            print(f"检查连接失败：{e}")
            return False

    # 判断 Wi-Fi 热点是否正在运行
    @staticmethod
    def is_wifi_hotspot_active(ssid: str = "") -> bool:
        """
        判断当前是否有正在运行的 Wi-Fi 热点连接（可指定名称）
        :param ssid: 可选参数，指定要检查的热点名称（如 '2C Device'）
        :return: 如果热点正在运行，返回 True；否则 False
        """
        try:
            # 获取所有活跃连接（格式：NAME:TYPE:DEVICE）
            output = os.popen("nmcli -t -f NAME,TYPE connection show --active").read().strip()
            lines = output.splitlines()

            for line in lines:
                name, ctype = line.split(":")
                if ctype == "wifi":
                    if ssid:
                        if name == ssid:
                            return True  # 指定的热点正在运行
                    else:
                        return True  # 任意 Wi-Fi 连接（可能是热点）在运行

            return False
        except Exception as e:
            log.error(f"检查热点状态失败: {e}")
            return False

    # 检查 Wi-Fi 是否已开启
    @staticmethod
    def is_wifi_enabled() -> bool:
        """
        检查系统中 Wi-Fi 是否已开启（即无线功能是否打开）
        :return: True 表示已开启，False 表示已关闭
        """
        try:
            status = os.popen("nmcli radio wifi").read().strip()
            return status.lower() == "enabled"
        except Exception as e:
            log.error(f"检查 Wi-Fi 状态失败: {e}")
            return False

    # 打开wifi开关
    @staticmethod
    def open_wifi():
        try:
            os.system("sudo nmcli radio wifi on")   # 打开 Wi-Fi 开关
        except Exception as e:
            log.error(f"open_wifi() -> except:{e}")

    # 关闭wifi开关
    @staticmethod
    def close_wifi():
        try:
            os.system("sudo nmcli radio wifi off")   # 关闭 Wi-Fi 开关
        except Exception as e:
            log.error(f"close_wifi() -> except:{e}")

    # 打开wifi热点 永久
    @staticmethod
    def open_wifi_hotspot_perpetual(ssid: str, password: str, ifname: str) -> bool:
        """
        创建并启用一个 Wi-Fi 热点，使用给定的 SSID 和密码。
        :param ssid: 热点名称（即网络名）
        :param password: 热点密码（使用 WPA-PSK 加密）
        :param ifname: 接口名称（如 wlan0）
        :return: 成功返回 True，失败返回 False
        """
        try:
            # 创建 Wi-Fi 热点连接（AP 模式）
            os.system(f"sudo nmcli con add type wifi ifname '{ifname}' con-name '{ssid}' autoconnect yes ssid '{ssid}'")

            # 设置为热点（AP）模式，使用共享网络
            os.system(f"sudo nmcli con modify '{ssid}' 802-11-wireless.mode ap 802-11-wireless.band bg ipv4.method shared")

            # 设置 WPA-PSK 密码
            os.system(f"sudo nmcli con modify '{ssid}' 802-11-wireless-security.key-mgmt wpa-psk")
            os.system(f"sudo nmcli con modify '{ssid}' 802-11-wireless-security.psk '{password}'")

            # 启动热点
            os.system(f"sudo nmcli con up '{ssid}'")

            log.info(f"Wi-Fi 热点已开启，SSID: {ssid}, 密码: {password}")
            return True
        except Exception as e:
            log.error(f"open_wifi_hotspot_perpetual() -> except:{e}")
            return False

    # 打开wifi热点 临时
    @staticmethod
    def open_wifi_hotspot_temporary(ssid: str, password: str, ifname: str) -> bool:
        """
        创建并启用一个 Wi-Fi 热点，使用给定的 SSID 和密码。
        :param ssid: 热点名称（即网络名）
        :param password: 热点密码（使用 WPA-PSK 加密）
        :param ifname: 接口名称（如 wlan0）
        :return: 成功返回 True，失败返回 False
        """
        try:
            os.system(f'sudo /usr/bin/nmcli dev wifi hotspot ifname "{ifname}" con-name "{ssid}" ssid "{ssid}" password "{password}"')
            log.info(f"Wi-Fi 热点已开启，SSID: {ssid}, 密码: {password}")
            return True
        except Exception as e:
            log.error(f"open_wifi_hotspot_temporary() -> except:{e}")
            return False

    # 关闭wifi热点
    @staticmethod
    def close_wifi_hotspot(ssid: str) -> bool:
        try:
            os.system(f"sudo nmcli con down '{ssid}'")
            os.system(f"sudo nmcli con delete '{ssid}'")
            log.info(f"Wi-Fi 热点已关闭，SSID: {ssid}")
            return True
        except Exception as e:
            log.error(f"close_wifi_hotspot() -> except:{e}")
            return False

    # 线程开启wifi、创建TCP服务器
    def open_wifi_hotspot_thread(self, wifi_name:str, host_ip: str, host_port: int):
        try:
            # 打开wifi
            for _ in range(3):
                if self.is_wifi_enabled():
                    log.debug(f"wifi已开启")
                    break
                else:
                    log.debug(f"打开wifi...")
                    self.open_wifi()
                    time.sleep(5)

            # 打开热点
            if not self.hotspot_connection_exists(wifi_name):   # 没有该热点连接
                ifname = self.get_wifi_ifname()     # 获取wifi接口名称
                mySignal.wifi_ifname_signal.emit(ifname)  # wifi网卡名称获取事件（str：网卡名称）
                if ifname:
                    wifi_password = mySetting.param.wifi_password
                    for _ in range(3):
                        if self.open_wifi_hotspot_perpetual(wifi_name, wifi_password, ifname):
                            log.debug(f"热点已开启，SSID: {wifi_name}, 密码: {wifi_password}")
                            self.tcp_server.start_server(host_ip, host_port)  # 开启服务器
                            break
                        else:
                            log.warning("创建热点失败，正在重试...")
                            self.close_wifi_hotspot(wifi_name)  # 关闭热点
                        time.sleep(5)
                else:
                    log.warning("无法获取wifi接口名称")
            else:
                log.debug(f"热点已存在，SSID: {wifi_name}")
                self.tcp_server.start_server(host_ip, host_port)  # 开启服务器

        except Exception as e:
            log.error(f"open_wifi_hotspot_thread() -> except:{e}")

    """wifi客户端----------------------------------------------------------------------------"""
    # 查找附近的 Wi-Fi 热点
    @staticmethod
    def scan_wifi_hotspots() -> list:
        """
        扫描周围的 Wi-Fi 热点，并返回 SSID 列表。
        :return: 热点的 SSID 列表
        """
        try:
            output = os.popen("nmcli -t -f SSID dev wifi list").read().strip()
            if output:
                return output.splitlines()
            else:
                return []
        except Exception as e:
            log.error(f"扫描附近的 Wi-Fi 热点失败: {e}")
            return []

    # 判断是否存在某个特定的热点
    @staticmethod
    def is_hotspot_available(ssid: str) -> bool:
        """
        检查是否存在某个特定名称的 Wi-Fi 热点。
        :param ssid: 要检查的 Wi-Fi 热点名称
        :return: 如果存在该热点，返回 True；否则返回 False
        """
        try:
            hotspots = WifiManger.scan_wifi_hotspots()
            return ssid in hotspots
        except Exception as e:
            log.error(f"检查 Wi-Fi 热点失败: {e}")
            return False

    # 连接到某个 Wi-Fi 热点
    @staticmethod
    def connect_to_hotspot(ssid: str, password: str) -> bool:
        """
        连接到指定的 Wi-Fi 热点。
        :param ssid: 热点的 SSID
        :param password: 热点密码
        :return: 成功连接返回 True，否则返回 False
        """
        try:
            os.system(f"sudo nmcli dev wifi connect '{ssid}' password '{password}'")
            log.info(f"成功连接到 Wi-Fi 热点: {ssid}")
            return True
        except Exception as e:
            log.error(f"连接到热点 {ssid} 失败: {e}")
            return False

    # 连接失败时的重试机制
    @staticmethod
    def retry_connect_hotspot(ssid: str, password: str, retries: int = 3):
        """
        重试连接到某个热点。
        :param ssid: 热点名称
        :param password: 热点密码
        :param retries: 重试次数
        """
        attempt = 0
        while attempt < retries:
            if WifiManger.connect_to_hotspot(ssid, password):
                log.info(f"成功连接到 Wi-Fi 热点 {ssid}")
                return True
            else:
                attempt += 1
                log.warning(f"连接失败，重试 {attempt}/{retries} 次")
                time.sleep(5)  # 等待 5 秒后重试
        log.error(f"无法连接到 Wi-Fi 热点 {ssid}，重试次数已用完")
        return False

